home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 4 / QRZ Ham Radio Callsign Database - Volume 4.iso / files / satelite / msat09.tgz / XPG.C < prev    next >
Text File  |  1994-09-17  |  13KB  |  521 lines

  1. /*
  2.  *   Copyright 1992, 1993, 1994 John Melton (G0ORX/N6LYT)
  3.  *              All Rights Reserved
  4.  *
  5.  *   This program is free software; you can redistribute it and/or modify
  6.  *   it under the terms of the GNU General Public License as published by
  7.  *   the Free Software Foundation; either version 1, or (at your option)
  8.  *   any later version.
  9.  *
  10.  *   This program is distributed in the hope that it will be useful,
  11.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *   GNU General Public License for more details.
  14.  *
  15.  *   You should have received a copy of the GNU General Public License
  16.  *   along with this program; if not, write to the Free Software
  17.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20.  
  21. /*
  22.     xpg.c
  23.  
  24.     Pacsat Upload for Linux and X-Windows
  25.  
  26.     This program has been run using the 1.0 version of the
  27.     Linux kernel with the patches from Alan Cox to provide AX.25
  28.     encapsulation in the SLIP protocol(verion 0.12).
  29.  
  30.     The TNC must be setup for KISS protocol.
  31.  
  32.     John Melton
  33.     G0ORX, N6LYT
  34.  
  35.     4 Charlwoods Close
  36.     Copthorne
  37.     West Sussex
  38.     RH10 3QZ
  39.     England
  40.  
  41.     INTERNET:    g0orx@amsat.org
  42.             n6lyt@amsat.org
  43.             john@images.demon.co.uk
  44.             J.D.Melton@slh0613.icl.wins.co.uk
  45.  
  46.     History:
  47.  
  48.     0.1    initial version.            G0ORX
  49.     0.2    added output ready notify code.        G0ORX
  50.     0.3    fixed error conditions - back to IDLE.    G0ORX
  51.     0.4    fixed restart upload of partial file.    G0ORX
  52.     0.5    converted to Xaw.            G4KLX
  53.         converted program to use a child process to upload file.
  54.     0.6    added double click for upload.        G4KLX
  55. */
  56.  
  57. #define VERSION_STRING "(version 0.6 by g0orx/n6lyt/g4klx)"
  58.  
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <unistd.h>
  62. #include <sys/types.h>
  63. #include <sys/wait.h>
  64. #include <fcntl.h>
  65. #include <dirent.h>
  66. #include <sys/socket.h>
  67. #include <signal.h>
  68. #include <ctype.h>
  69.  
  70. #include <X11/Intrinsic.h>
  71. #include <X11/StringDefs.h>
  72. #include <X11/Shell.h>
  73. #include <X11/Xaw/Cardinals.h>
  74. #include <X11/Xaw/Form.h>
  75. #include <X11/Xaw/Label.h>
  76. #include <X11/Xaw/List.h>
  77. #include <X11/Xaw/Command.h>
  78. #include <X11/Xaw/MenuButton.h>
  79. #include <X11/Xaw/SimpleMenu.h>
  80. #include <X11/Xaw/SmeBSB.h>
  81. #include <X11/Xaw/Viewport.h>
  82.  
  83. #include "xawutils.h"
  84. #include "header.h"
  85. #include "ftl0.h"
  86.  
  87. Display *dpy;
  88.  
  89. XtAppContext app_context;
  90.  
  91. typedef struct
  92. {
  93.     XFontStruct *bold_font, *button_font, *menu_font, *label_font, *list_font;
  94. }
  95. Resources;
  96.  
  97. Resources  resources;
  98.  
  99. Widget toplevel, compwindow, quitbutton, updatebutton, messagebutton,
  100.     statuslabel, listlabel, viewport, uploadlist;
  101.  
  102. static XtResource resource_list[] =
  103. {
  104.     {"boldFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  105.         XtOffsetOf(Resources, bold_font), XtRString, XtDefaultFont},
  106.     {"buttonFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  107.         XtOffsetOf(Resources, button_font), XtRString, XtDefaultFont},
  108.     {"menuFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  109.         XtOffsetOf(Resources, menu_font), XtRString, XtDefaultFont},
  110.     {"labelFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  111.         XtOffsetOf(Resources, label_font), XtRString, XtDefaultFont},
  112.     {"listFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  113.         XtOffsetOf(Resources, list_font), XtRString, XtDefaultFont}
  114. };
  115.  
  116. static Arg shell_args[] =
  117. {
  118.     {XtNtitle,        (XtArgVal)NULL}
  119. };
  120.  
  121. static Arg form_args[] =
  122. {
  123.     {XtNdefaultDistance,    (XtArgVal)0}
  124. };
  125.  
  126. static Arg label_args[] =
  127. {
  128.     {XtNfromVert,        (XtArgVal)NULL},
  129.     {XtNfromHoriz,        (XtArgVal)NULL},
  130.     {XtNlabel,        (XtArgVal)NULL},
  131.     {XtNwidth,        (XtArgVal)0},
  132.     {XtNfont,        (XtArgVal)NULL},
  133.     {XtNborderWidth,    (XtArgVal)0},
  134.     {XtNresize,        False},
  135.     {XtNjustify,        XtJustifyLeft},
  136.     {XtNvertDistance,    (XtArgVal)6},
  137.     {XtNhorizDistance,    (XtArgVal)8},
  138.     {XtNtop,        XtChainTop},
  139.     {XtNbottom,        XtChainTop},
  140.     {XtNleft,        XtChainLeft},
  141.     {XtNright,        XtChainLeft}
  142. };
  143.  
  144. static Arg button_args[] =
  145. {
  146.     {XtNcallback,        (XtArgVal)NULL},
  147.     {XtNlabel,        (XtArgVal)NULL},
  148.     {XtNfont,        (XtArgVal)NULL},
  149.     {XtNfromHoriz,        (XtArgVal)NULL},
  150.     {XtNfromVert,        (XtArgVal)NULL},
  151.     {XtNvertDistance,    (XtArgVal)6},
  152.     {XtNhorizDistance,    (XtArgVal)8},
  153.     {XtNresize,        False},
  154.     {XtNtop,        XtChainTop},
  155.     {XtNbottom,        XtChainTop},
  156.     {XtNleft,        XtChainLeft},
  157.     {XtNright,        XtChainLeft}
  158. };
  159.  
  160. static Arg viewport_args[] =
  161. {
  162.     {XtNfromVert,        (XtArgVal)NULL},
  163.     {XtNwidth,        (XtArgVal)600},
  164.     {XtNheight,        (XtArgVal)150},
  165.     {XtNforceBars,        True},
  166.     {XtNallowVert,        True},
  167.     {XtNresize,        True},
  168.     {XtNvertDistance,    (XtArgVal)0},
  169.     {XtNhorizDistance,    (XtArgVal)0},
  170.     {XtNtop,        XtChainTop},
  171.     {XtNbottom,        XtChainBottom},
  172.     {XtNleft,        XtChainLeft},
  173.     {XtNright,        XtChainRight}
  174. };
  175.  
  176. static Arg list_args[] =
  177. {
  178.     {XtNcallback,        (XtArgVal)NULL},
  179.     {XtNfont,        (XtArgVal)NULL}
  180. };
  181.  
  182. #define    MAX_DIR_LIST_SIZE    2000
  183.  
  184. String dList[MAX_DIR_LIST_SIZE + 1];
  185. int    nList = 0;
  186.  
  187. int lastIndex = 0;
  188.  
  189. char satellite[16];
  190. char myCall[16];
  191.  
  192. XtInputId infd;
  193. int fd[2];
  194. int uploadpid = 0;
  195. int maxFrame;
  196. int T1;
  197.  
  198. extern void upload(char *);
  199.     
  200. void QuitCb(Widget w, XtPointer client_data, XtPointer call_data)
  201. {
  202.     if (uploadpid != 0)
  203.     {
  204.         kill(uploadpid, SIGINT);
  205.     }
  206.  
  207.     XtDestroyApplicationContext(app_context);
  208.     
  209.     exit(0);
  210. }
  211.  
  212. void LoadFile(char * fileName)
  213. {
  214.     FILE *hFile;
  215.     int nBytes, j;
  216.     char *pBuffer, *p;
  217.     char szTemp[128];
  218.     int headerSize;
  219.     HEADER *pHeader;
  220.     int fileNumber;
  221.  
  222.     sscanf(fileName, "%x", &fileNumber);
  223.  
  224.     /* open the file */
  225.     if ((hFile = fopen(fileName, "r")) == NULL)
  226.     {
  227.         perror(fileName);
  228.         return;
  229.     }
  230.  
  231.     /* extracting the header */
  232.     pBuffer = XtMalloc(1024);
  233.  
  234.     nBytes = fread(pBuffer, 1, 1024, hFile);
  235.  
  236.     fclose(hFile);
  237.  
  238.     if ((pHeader = ExtractHeader(pBuffer, nBytes, &headerSize)) == NULL)
  239.     {
  240.         printf("invalid header entry for file: %s\n", fileName);
  241.     }
  242.     else
  243.     {
  244.         /* truncate the source and destination */
  245.         for (j = 0; isalnum(pHeader->source[j]); j++);
  246.               pHeader->source[j] = '\0';
  247.  
  248.         for (j = 0; isalnum(pHeader->destination[j]); j++);
  249.               pHeader->destination[j] = '\0';
  250.  
  251.         if (strlen(pHeader->title) == 0)
  252.             sprintf(szTemp, "%12s %8lx %-8s %6ld %-45s",
  253.                 fileName, pHeader->fileId, pHeader->destination,
  254.                 pHeader->fileSize, pHeader->fileName);
  255.         else
  256.             sprintf(szTemp, "%12s %8lx %-8s %6ld %-45s",
  257.                 fileName, pHeader->fileId, pHeader->destination,
  258.                 pHeader->fileSize, pHeader->title);
  259.  
  260.         for (p = pHeader->source; *p != '\0'; p++)
  261.             if (islower(*p)) *p = toupper(*p);
  262.  
  263.         for (p = pHeader->destination; *p != '\0'; p++)
  264.             if (islower(*p)) *p = toupper(*p);
  265.  
  266.         dList[nList] = XtNewString(szTemp);
  267.         nList++;
  268.  
  269.         XtFree((char *)pHeader);
  270.     }
  271.  
  272.     XtFree(pBuffer);
  273. }
  274.  
  275. void Update(void)
  276. {
  277.     DIR        *pDir;
  278.     struct dirent    *pDirent;
  279.     int i;
  280.     Arg args[2];
  281.  
  282.     for (i = 0; i < nList; i++)
  283.         if (dList[i] != NULL)
  284.             XtFree(dList[i]);
  285.  
  286.     nList     = 0;
  287.     lastIndex = -1;
  288.  
  289.     /* walk through the directory of files */
  290.     pDir = opendir(".");
  291.  
  292.     while ((pDirent = readdir(pDir)) != NULL)
  293.     {
  294.         /* see if it is a .upl file */
  295.         if (strstr(&pDirent->d_name[i], ".upl") != NULL)
  296.             LoadFile(pDirent->d_name);
  297.     }
  298.  
  299.     closedir(pDir);
  300.  
  301.     dList[nList] = NULL;
  302.  
  303.     XawListChange(uploadlist, dList, nList, 0, False);
  304.  
  305.     if (nList > 0) XawListHighlight(uploadlist, 0);
  306.  
  307.     XtSetArg(args[0], XtNheight, 0);
  308.     XtSetArg(args[1], XtNwidth,  0);
  309.     XtSetValues(uploadlist, args, TWO);
  310. }
  311.  
  312. void UpdateCb(Widget w, XtPointer client_data, XtPointer call_data)
  313. {
  314.     Update();
  315. }
  316.  
  317. void ReceivedStatus(XtPointer closure, int *s, XtInputId *Id)
  318. {
  319.     int bytes;
  320.     char msg[200];
  321.     
  322.     bytes = read(fd[0], msg, 200);
  323.  
  324.     XtVaSetValues(statuslabel, XtNlabel, msg, NULL);
  325. }
  326.  
  327. void SelectCb(Widget w, XtPointer client_data, XtPointer call_data)
  328. {
  329.     XawListReturnStruct *selected;
  330.     unsigned long FileId;
  331.     char fileName[30];
  332.  
  333.     if (uploadpid != 0)
  334.     {
  335.         MessageBox("Upload already in progress");
  336.         return;
  337.     }
  338.  
  339.     selected = (XawListReturnStruct *)call_data;
  340.     
  341.     if (selected->list_index != lastIndex)
  342.     {
  343.         lastIndex = selected->list_index;
  344.         return;
  345.     }
  346.  
  347.     lastIndex = -1;
  348.         
  349.     sscanf(selected->string, "%lx", &FileId);
  350.     sprintf(fileName, "%lx.upl", FileId);
  351.  
  352.     pipe(fd);
  353.  
  354.     if ((uploadpid = fork()) == 0)
  355.     {
  356.         /* the child process */
  357.         upload(fileName);
  358.     }
  359.     else if (uploadpid > 0)
  360.     {
  361.         /* success */
  362.         infd = XtAppAddInput(app_context, fd[0], (XtPointer)XtInputReadMask,
  363.                      ReceivedStatus, NULL);
  364.     }
  365.     else
  366.     {
  367.         MessageBox("Cannot fork upload");
  368.     }
  369. }
  370.  
  371. void signal_child(int s)
  372. {
  373.     int pstatus;
  374.  
  375.     signal(SIGCHLD, signal_child);
  376.  
  377.     if (wait(&pstatus) == uploadpid)
  378.     {
  379.         XtRemoveInput(infd);
  380.         uploadpid = 0;
  381.     }
  382.  
  383.     Update();
  384. }
  385.  
  386. void MessageCb(Widget w, XtPointer client_data, XtPointer call_data)
  387. {
  388.     int pid;
  389.  
  390.     if ((pid = fork()) == 0)
  391.     {
  392.         /* the child process */
  393.         execlp("message", "message", NULL);
  394.     }
  395.     else if (pid > 0)
  396.     {
  397.         /* success */
  398.     }
  399.     else
  400.     {
  401.         MessageBox("Cannot fork message");
  402.     }
  403. }
  404.  
  405. int main(int argc, char **argv)
  406. {
  407.     static XtCallbackRec callback[2];
  408.     char title[80], *s;
  409.  
  410.     signal(SIGCHLD, signal_child);
  411.  
  412.     if ((s = getenv("SATELLITE")) == NULL)
  413.     {
  414.         printf("SATELLITE environment variable not set.\n");
  415.         return(1);
  416.     }
  417.     
  418.     strcpy(satellite, s);
  419.  
  420.     if ((s = getenv("MYCALL")) == NULL)
  421.     {
  422.         printf("MYCALL environment variable not set.\n");
  423.         return(1);
  424.     }
  425.  
  426.     strcpy(myCall, s);
  427.     
  428.     if ((s= getenv("MAXFRAMEDATA")) == NULL)
  429.         maxFrame = 200;
  430.     else
  431.         maxFrame = atoi(s);
  432.  
  433.     if (maxFrame <= 0 || maxFrame >= 256) maxFrame = 200;
  434.  
  435.     if ((s = getenv("T1")) == NULL)
  436.         T1 = 20;
  437.     else
  438.         T1 = atoi(s);
  439.  
  440.     if (T1 <= 0) T1 = 20;
  441.  
  442.     sprintf(title, "xpg:%s %s", satellite, VERSION_STRING);
  443.  
  444.     strcat(satellite, "-12");
  445.  
  446.     toplevel = XtAppInitialize(&app_context, "Xpb", NULL, 0, &argc, argv,
  447.                 NULL, shell_args, XtNumber(shell_args));
  448.  
  449.     XtVaSetValues(toplevel, XtNtitle, title, NULL);
  450.  
  451.     dpy  = XtDisplay(toplevel);
  452.  
  453.     XtGetApplicationResources(toplevel, &resources,
  454.                 resource_list, XtNumber(resource_list),
  455.                 NULL, ZERO);
  456.  
  457.     compwindow = XtCreateManagedWidget("appForm", formWidgetClass,
  458.                 toplevel, form_args, XtNumber(form_args));
  459.  
  460.     callback[0].callback = QuitCb;
  461.     callback[0].closure  = toplevel;
  462.     button_args[0].value = (XtArgVal)callback;
  463.     button_args[1].value = (XtArgVal)"Quit";
  464.     button_args[2].value = (XtArgVal)resources.button_font;
  465.     quitbutton = XtCreateManagedWidget("quitButton", commandWidgetClass,
  466.                 compwindow, button_args, XtNumber(button_args));
  467.  
  468.     callback[0].callback = UpdateCb;
  469.     callback[0].closure  = toplevel;
  470.     button_args[0].value = (XtArgVal)callback;
  471.     button_args[1].value = (XtArgVal)"Update";
  472.     button_args[3].value = (XtArgVal)quitbutton;
  473.     updatebutton = XtCreateManagedWidget("updateButton", commandWidgetClass,
  474.                 compwindow, button_args, XtNumber(button_args));
  475.  
  476.     callback[0].callback = MessageCb;
  477.     callback[0].closure  = toplevel;
  478.     button_args[0].value = (XtArgVal)callback;
  479.     button_args[1].value = (XtArgVal)"Message";
  480.     button_args[3].value = (XtArgVal)updatebutton;
  481.     messagebutton = XtCreateManagedWidget("messageButton", commandWidgetClass,
  482.                 compwindow, button_args, XtNumber(button_args));
  483.  
  484.     label_args[0].value = (XtArgVal)NULL;
  485.     label_args[1].value = (XtArgVal)messagebutton;
  486.     label_args[2].value = (XtArgVal)"Status: Idle";
  487.     label_args[3].value = (XtArgVal)350;
  488.     label_args[4].value = (XtArgVal)resources.button_font;
  489.     statuslabel = XtCreateManagedWidget("statusLabel", labelWidgetClass,
  490.                 compwindow, label_args, XtNumber(label_args));
  491.  
  492.     label_args[0].value = (XtArgVal)quitbutton;
  493.     label_args[1].value = (XtArgVal)NULL;
  494.     label_args[2].value = (XtArgVal)" File               Id To         Size Title";
  495.     label_args[3].value = (XtArgVal)500;
  496.     label_args[4].value = (XtArgVal)resources.list_font;
  497.     listlabel = XtCreateManagedWidget("listLabel", labelWidgetClass,
  498.                 compwindow, label_args, XtNumber(label_args));
  499.  
  500.     viewport_args[0].value = (XtArgVal)listlabel;
  501.     viewport = XtCreateManagedWidget("uploadViewport", viewportWidgetClass,
  502.                 compwindow, viewport_args, XtNumber(viewport_args));
  503.         
  504.     callback[0].callback = SelectCb;
  505.     callback[0].closure  = toplevel;
  506.     list_args[0].value = (XtArgVal)callback;
  507.     list_args[1].value = (XtArgVal)resources.list_font;
  508.     uploadlist = XtCreateManagedWidget("uploadList", listWidgetClass,
  509.                 viewport, list_args, XtNumber(list_args));
  510.  
  511.     createMessagePopup(resources.bold_font, resources.button_font);
  512.  
  513.     Update();
  514.  
  515.     XtRealizeWidget(toplevel);
  516.  
  517.     XtAppMainLoop(app_context);
  518.  
  519.     return(0);
  520. }
  521.